﻿using iTuner;
using NLog;
using PPP.ViewModel.BaseModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;

namespace PPP.ViewModel.WindowModel {
    /// <summary>
    /// ViewModel for a the usb connector. 
    /// 
    /// <list type="bullet">
    /// <item>
    /// <term>Author</term>
    /// <description>Sebastian Will</description>
    /// </item>
    /// </list>
    /// 
    /// </summary>
    public class USBViewModel : ToolViewModel {

        #region Fields
        private readonly Logger _logger = LogManager.GetLogger("USBViewModel");
        private UsbManager _usbManager;

        /// <summary>
        /// The collection of the usb devices.
        /// </summary>
        private ObservableCollection<DeviceUSBViewModel> _usbDevices = null;

        /// <summary>
        /// The selected usb device.
        /// </summary>
        private DeviceUSBViewModel _selectedUSBDevice = null;

        #endregion

        #region Consts

        /// <summary>
        /// The dockable content content id.
        /// </summary>
        public const string ToolContentId = "USBTool";

        #region PropertyName Consts

        /// <summary>
        /// The <see cref="SelectedUSBDevice" /> property's name.
        /// </summary>
        public const string SelectedUSBDevicePropertyName = "SelectedUSBDevice";

        #endregion
        #endregion

        #region Properties

        /// <summary>
        /// Gets the collection of the usb devices property.
        /// </summary>
        public ObservableCollection<DeviceUSBViewModel> USBDevices {
            get {
                if (_usbDevices == null)
                    _usbDevices = new ObservableCollection<DeviceUSBViewModel>();

                return _usbDevices;
            }

            set { _usbDevices = value; }
        }

        /// <summary>
        /// Gets the SelectedUSBDevice property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public DeviceUSBViewModel SelectedUSBDevice {
            get {
                return _selectedUSBDevice;
            }

            set {
                if (_selectedUSBDevice == value) {
                    return;
                }

                var oldValue = _selectedUSBDevice;
                _selectedUSBDevice = value;
                
                RaisePropertyChanged(SelectedUSBDevicePropertyName, oldValue, _selectedUSBDevice, true);
            }
        }

        #region Commands
        #endregion
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the USBViewModel class.
        /// </summary>        
        public USBViewModel()
            : base(Properties.ResourcesPaneTitle.USBConnectorPane) {
            //MainViewModel.This.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged);
            ContentId = ToolContentId;

            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.UriSource = new Uri("pack://application:,,,/PPP;component/icons/gui/usb.png");
            bi.EndInit();
            IconSource = bi;


            InitUSBManager();
        }

        #endregion

        #region Methods

        /// <summary>
        /// Init the USB manager.
        /// </summary>
        private void InitUSBManager() {

            _usbManager = new UsbManager();
            UsbDiskCollection devices = _usbManager.GetAvailableDisks();

            foreach (UsbDisk device in devices) {
                _logger.Info("Available USB disks: {0}", device.ToString());
                USBDevices.Add(new DeviceUSBViewModel(device));
            }

            _usbManager.StateChanged += new UsbStateChangedEventHandler(USBManager_StateChanged);

            
        }

        #endregion

        #region Events
        /// <summary>
        /// Fired when the usb manager detect a state change. A usb devive is added or removed.
        /// </summary>
        /// <param name="e">The UsbStateChangedEventArgs event args.</param>
        private void USBManager_StateChanged(UsbStateChangedEventArgs e) {

            bool result = false;

            _logger.Info("{0} {1}", e.State, e.Disk.ToString());

            switch (e.State) {
                case UsbStateChange.Added:
                    USBDevices.Add(new DeviceUSBViewModel(e.Disk));
                    break;
                case UsbStateChange.Removed:
                    DeviceUSBViewModel device = USBDevices.FirstOrDefault(t => t.USBDevice.Name == e.Disk.Name);
                    if(device != null)
                        result = USBDevices.Remove(device); 
                    break;
                case UsbStateChange.Removing:
                    break;
                default:
                    break;
            }
                                             
        }
        #endregion
    }
}
